# -*- coding: utf-8 -*-
"""
    xfree.user.forms
    ~~~~~~~~~~~~~~~~~~~~~
    文件描述：这个模块提供了用户视图所需的表单。
    作者：xfree
    邮箱：cy_83k@qq.com
"""

import logging

# 从flask_babelplus导入lazy_gettext并简写成_，用于处理多语言文本
from flask_babelplus import lazy_gettext as _
# 从wtforms导入多个表单字段类型
from wtforms import (
    DateField,
    PasswordField,
    SelectField,
    StringField,
    SubmitField,
    TextAreaField,
)
# 从wtforms.validators导入多个表单验证器
from wtforms.validators import (
    URL,
    DataRequired,
    Email,
    EqualTo,
    InputRequired,
    Length,
    Optional,
)

# 从xfree.utils.forms导入XFreeForm，可能是自定义的表单基类
from xfree.utils.forms import XFreeForm

# 从相对路径下的模块导入多个用户数据更新相关的类
from..core.user.update import (
    EmailUpdate,
    PasswordUpdate,
    SettingsUpdate,
    UserDetailsChange,
)

logger = logging.getLogger(__name__)


class GeneralSettingsForm(XFreeForm):
    """
    通用设置表单类

    表单中的语言和主题选择字段的选项将在用户视图中生成，
    因为在上下文之外无法访问当前应用（current_app）
    """
    # 语言选择字段，选项将在视图中生成
    language = SelectField(_("Language"))
    # 主题选择字段，选项将在视图中生成
    theme = SelectField(_("Theme"))
    # 提交按钮
    submit = SubmitField(_("Save"))

    def as_change(self):
        """
        将表单数据转换为SettingsUpdate对象

        :return: SettingsUpdate对象，包含语言和主题数据
        """
        return SettingsUpdate(language=self.language.data, theme=self.theme.data)


class ChangeEmailForm(XFreeForm):
    """
    修改电子邮件表单类
    """
    old_email = StringField(
        _("Old email address"),
        validators=[
            # 数据必填验证，提示信息为需要有效的电子邮件地址
            DataRequired(message=_("A valid email address is required.")),
            # 电子邮件格式验证，提示信息为无效的电子邮件地址
            Email(message=_("Invalid email address.")),
        ],
    )
    new_email = StringField(
        _("New email address"),
        validators=[
            # 输入必填验证
            InputRequired(),
            # 与确认新电子邮件字段值相等验证，提示信息为电子邮件地址必须匹配
            EqualTo("confirm_new_email", message=_("Email addresses must match.")),
            # 电子邮件格式验证，提示信息为无效的电子邮件地址
            Email(message=_("Invalid email address.")),
        ],
    )
    confirm_new_email = StringField(
        _("Confirm email address"),
        validators=[Email(message=_("Invalid email address."))],
    )
    submit = SubmitField(_("Save"))

    def __init__(self, user, *args, **kwargs):
        """
        表单初始化方法

        :param user: 用户对象
        :param args: 其他位置参数
        :param kwargs: 其他关键字参数
        """
        self.user = user
        kwargs["obj"] = self.user
        super(ChangeEmailForm, self).__init__(*args, **kwargs)

    def as_change(self):
        """
        将表单数据转换为EmailUpdate对象

        :return: EmailUpdate对象，包含旧电子邮件和新电子邮件数据
        """
        return EmailUpdate(old_email=self.old_email.data, new_email=self.new_email.data)


class ChangePasswordForm(XFreeForm):
    """
    修改密码表单类
    """
    old_password = PasswordField(
        _("Password"),
        validators=[DataRequired(message=_("Please enter your password."))],
    )
    new_password = PasswordField(
        _("New password"),
        validators=[
            # 输入必填验证
            InputRequired(),
            # 与确认新密码字段值相等验证，提示信息为新密码必须匹配
            EqualTo("confirm_new_password", message=_("New passwords must match.")),
        ],
    )
    confirm_new_password = PasswordField(_("Confirm new password"))
    submit = SubmitField(_("Save"))

    def as_change(self):
        """
        将表单数据转换为PasswordUpdate对象

        :return: PasswordUpdate对象，包含新密码和旧密码数据
        """
        return PasswordUpdate(
            new_password=self.new_password.data, old_password=self.old_password.data
        )


class ChangeUserDetailsForm(XFreeForm):
    """
    修改用户详细信息表单类
    """
    birthday = DateField(_("Birthday"), format="%Y-%m-%d", validators=[Optional()])
    gender = StringField(_("Gender"), validators=[Optional()])
    location = StringField(_("Location"), validators=[Optional()])
    website = StringField(_("Website"), validators=[Optional(), URL()])
    avatar = StringField(_("Avatar"), validators=[Optional(), URL()])
    signature = TextAreaField(_("Forum Signature"), validators=[Optional()])
    notes = TextAreaField(_("Notes"), validators=[Optional(), Length(min=0, max=5000)])
    submit = SubmitField(_("Save"))

    def validate_birthday(self, field):
        """
        验证生日字段

        :param field: 生日字段对象
        :return: 如果字段数据为None则返回True，否则不做处理
        """
        if field.data is None:
            return True

    def as_change(self):
        """
        将表单数据转换为UserDetailsChange对象

        :return: UserDetailsChange对象，包含用户详细信息数据
        """
        return UserDetailsChange(
            birthday=self.birthday.data,
            gender=self.gender.data,
            location=self.location.data,
            website=self.website.data,
            avatar=self.avatar.data,
            signature=self.signature.data,
            notes=self.notes.data,
        )